<?php

class SessionManager
{
	public $data;
	public $sessionID;
	public $userID;
	
	public static $cookieName = 'fqssn';
	public static $sessionDuration = 1800; // i.e. until browser is closed
	
	/**
	 * The current session; null if no valid session
	 * @var SessionManager
	 */ 
	public static $instance;
	
	/**
	 * @return SessionManager
	 */
	public static function create($userID)
	{
		$ssn = new SessionManager();
		$rand = rand(0, 1000000);
		$ssn->sessionID = sha1($rand);

		DBUtils::instance()->execute('Insert into sessions (session_id, user_id, session_ip, last_access) values (?, ?, ?, now())',
					 array($ssn->sessionID, $userID, $_SERVER['REMOTE_ADDR']));
	
		setcookie(SessionManager::$cookieName, $ssn->sessionID, time() + SessionManager::$sessionDuration);
		
		$ssn->data = array(
			'user'=>DBUtils::instance()->selectSingleVO("Select * from users where user_id = ?", array($userID), true)
		);
		$ssn->save();
		SessionManager::$instance = $ssn; 

		return $ssn;
	}
	
	/**
	 * Tries to load the user session from the cookie
	 * @return SessionManager
	 */
	public static function loadFromCookie()
	{
		$id = $_COOKIE[SessionManager::$cookieName];

		if(empty($id))
			return null;
		
		$ssn = new SessionManager();
		try
		{
			$ssn->load($id);
			
			SessionManager::$instance = $ssn;
			
			return $ssn;
		}
		catch(Exception $e)
		{
			return null;
		}
	}
	/**
	 * Loads a session by its ID. Throws an exception if no session found 
	 * @param string $sessionID
	 */
	public function load($sessionID)
	{
		$vo = DBUtils::instance()->selectSingleVO("Select * from sessions where session_id = ?", 
										array($sessionID));

		if(!$vo)
			throw new Exception("No session found");

		$this->sessionID = $sessionID;
		$this->userID = $vo->USER_ID;
		$this->data = unserialize($vo->SESSION_DATA);
		
		//Update last access time
		DBUtils::instance()->execute("Update sessions set last_access = now() where session_id = ?", 
							array($sessionID));
	}
	
	public function save()
	{
		$serialized = serialize($this->data);
		
		DBUtils::instance()->execute("Update sessions set session_data = ? where session_id = ?",
							array($serialized, $this->sessionID));
	}
	
	public function destroy()
	{
		DBUtils::instance()->execute("Delete from sessions where session_id = ?", 
							array($this->sessionID));
	}
	
}
?>